{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Syft Kerasを用いたプライバシーに配慮した予測"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ステップ1 : 公開データでの学習\n",
    "チュートリアルへようこそ！今回のノートブックでは、プライバシーに配慮した予測に関する手法について学習します。プライバシーに配慮した予測とは、データがプロセス全体を通して常に暗号化されることを意味します。ユーザーは生データを共有せず、暗号化された（つまり、秘密の共有）データのみを共有します。これらのプライバシーに配慮した予測を提供するために、Syft Kerasは内部で[TF Encrypted]（https://github.com/tf-encrypted/tf-encrypted）と呼ばれるライブラリを使用します。 TF Encryptedは、最先端の暗号技術と機械学習技術を組み合わせていますが、暗号技術について考慮する必要はなく、機械学習アプリケーションを利用できます。\n",
    "\n",
    "次の3つの手順でプライベート予測の配信を開始できます。\n",
    "-**ステップ1 **：通常のKerasを使用するモデルの学習\n",
    "-**ステップ2 **：機械学習モデル（サーバー）を保護した状態での提供。\n",
    "-**ステップ3 **：保護されたモデルにクエリを実行する、プライバシーに配慮した予測の受信(クライアント)。\n",
    "\n",
    "では、これらの3つの手順を実行して、ユーザーのプライバシーやモデルのセキュリティを無駄にすることなく、効果のある機械学習サービスを展開できるようにします。\n",
    "\n",
    "Authors:\n",
    "- Jason Mancuso - Twitter: [@jvmancuso](https://twitter.com/jvmancuso)\n",
    "- Yann Dupis - Twitter: [@YannDupis](https://twitter.com/YannDupis)\n",
    "- Morten Dahl - Twitter: [@mortendahlcs](https://github.com/mortendahlcs)\n",
    "\n",
    "On behalf of:\n",
    "- Dropout Labs - Twitter: [@dropoutlabs](https://twitter.com/dropoutlabs)\n",
    "- TF Encrypted - Twitter: [@tf_encrypted](https://twitter.com/tf_encrypted)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Keras使用するモデルの学習"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " [Keras](https://keras.io/) を使用するモデルの学習\n",
    "プロジェクトでプライバシーを保護する機械学習手法を使用するために、新しい機械学習フレームワークを学習する必要はありません。 Kerasの基本的な知識がある場合は、Syft Kerasでこれらの手法を使用して開始できます。以前にKerasを使用したことがない場合は、[Keras documentation](https://keras.io)のドキュメントで詳細を確認できます。\n",
    "\n",
    "プライバシーに配慮した予測の前に、最初のステップはモデルを通常のKerasでトレーニングする点です。例として、手書きの数字を分類するモデルをトレーニングします。このモデルをトレーニングするには、標準の[MNIST dataset](http://yann.lecun.com/exdb/mnist/)データセットを使用します。\n",
    "\n",
    "参照Kerasリポジトリから[this example](https://github.com/keras-team/keras/blob/master/examples/mnist_cnn.py) を用います。分類モデルをトレーニングするには、以下のセルを実行するだけです。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from __future__ import print_function\n",
    "import tensorflow.keras as keras\n",
    "from tensorflow.keras.datasets import mnist\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import Dense, Dropout, Flatten\n",
    "from tensorflow.keras.layers import Conv2D, AveragePooling2D\n",
    "from tensorflow.keras.layers import Activation\n",
    "\n",
    "batch_size = 128\n",
    "num_classes = 10\n",
    "epochs = 2\n",
    "\n",
    "# 入力の次元数\n",
    "img_rows, img_cols = 28, 28\n",
    "\n",
    "# 学習用とテスト用のデータに分割\n",
    "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
    "\n",
    "x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)\n",
    "x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)\n",
    "input_shape = (img_rows, img_cols, 1)\n",
    "\n",
    "x_train = x_train.astype('float32')\n",
    "x_test = x_test.astype('float32')\n",
    "x_train /= 255\n",
    "x_test /= 255\n",
    "print('x_train shape:', x_train.shape)\n",
    "print(x_train.shape[0], 'train samples')\n",
    "print(x_test.shape[0], 'test samples')\n",
    "\n",
    "# クラスラベルの変換\n",
    "y_train = keras.utils.to_categorical(y_train, num_classes)\n",
    "y_test = keras.utils.to_categorical(y_test, num_classes)\n",
    "\n",
    "model = Sequential()\n",
    "\n",
    "model.add(Conv2D(10, (3, 3), input_shape=input_shape))\n",
    "model.add(AveragePooling2D((2, 2)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(32, (3, 3)))\n",
    "model.add(AveragePooling2D((2, 2)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(64, (3, 3)))\n",
    "model.add(AveragePooling2D((2, 2)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Flatten())\n",
    "model.add(Dense(num_classes, activation='softmax'))\n",
    "\n",
    "model.compile(loss=keras.losses.categorical_crossentropy,\n",
    "              optimizer=keras.optimizers.Adam(),\n",
    "              metrics=['accuracy'])\n",
    "\n",
    "model.fit(x_train, y_train,\n",
    "          batch_size=batch_size,\n",
    "          epochs=epochs,\n",
    "          verbose=1,\n",
    "          validation_data=(x_test, y_test))\n",
    "score = model.evaluate(x_test, y_test, verbose=0)\n",
    "print('Test loss:', score[0])\n",
    "print('Test accuracy:', score[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 学習済みモデルの重みの保存"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "すごい！モデルは訓練済みです。`model.save()`でモデルの重みを保存しましょう。次のノートブックでは、この学習済みモデルの重みをSyft Kerasにロードして、プライベート予測の提供を開始します。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.save('short-conv-mnist.h5')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
